/**
* \mainpage Trix + MA4 <- Triple Exponential Average Indicator
*
*
*
* \section intro_sec Introducao
*
* � baseado nas m�dias m�veis exponenciais (EMA � Exponential Moving Average) de\n
* um per�odo de N dias e pode ser completado em 4 passos.\n
* A Exponential Moving Average(EMA)� calculada aplicando-se fatores de pondera��o que diminuem exponencialmente.\n
* A pondera��o para cada ponto de dados mais antigo decresce exponencialmente, dando\n
* muito mais import�ncia �s observa��es recentes, mas sem descartar as observa��es mais\n
* antigas por completo. Sendo formado por dois graficos composto pelo Trix e MA4(media movel simples da ultima serie do trix).
*
*
* @header      trix.h
* @version     1.1
* @date        20/10/2010
* @author      Rafael Tosta Santos <rafa.ecomp@gmail.com> \n
* @group       UEFS - Engenharia da Computacao
* @see         Projeto Anual I - Prof. Angelo Duarte\n Candelabro
* @link        Repositorio <http://candelabro.googlecode.com/svn/trunk/candelabro>
* @ref         Candelabro::trix
*
*/


#include "trix.h"
#include "bollingerbands.h"
#include <iostream>
#include <fstream>

/** Construtor vazio*/
Trix::Trix()
{
}

/** Realiza o calculo do Trix
 * Esse calculo eh realizado da seguinte forma:
 * EMA1: Calcula a media exponencial de n per�odos do pre�o de fechamento
 * EMA2: Calcula para n per�odos a m�dia m�vel exponencial de EMA1
 * EMA3: Calcula para n per�odos a m�dia m�vel exponencial de EMA2
 * Calcula TRIX: {(EMA3 [hoje] - EMA3 [ontem]) / EMA3 [ontem]} * 100
 *
 * @param <double> fechamento[] vetor com todos os fechamentos a ser calculado
 * @param <int> numDias quanidade de dias utilizado no vetor de fechamentos, ou seja, o tamanho do vetor de fechamento
 * @param <int> periodo periodo utilizado para a realizacao dos calculos,ou seja,
 *              eh a diferenca entre os valores conjuntos de valores que representa um vetor,
 *              por exemplo, entre a MME1 e a MME2 a diferenca de valores entre eles � definido pelo periodo
 * @param <int> qtDiasDesejados quantidade de dias desejados para o calculo,
 *              esse valor eh utilizado para o calculo da variavel K que eh definida como
 *              sendo 2/(n+1), sendo n a quantidade de dias desejados para a realizacao do calculo
 *
*/
void Trix::calculoTrix(double *fechamento, int numDias, int periodo,int qtDiasDesejados){

    this->periodo = periodo;

    this->k = 2.0/(qtDiasDesejados + 1.0);


    double *MME1 = this->EMAClose1(fechamento,numDias); //1� passo!
    double *MME2 = this->EMAClose2And3(MME1,numDias); //2� passo!
    double *MME3 = this->EMAClose2And3(MME2,numDias - this->periodo); //3� passo!

    //pontos do grafico trix 4
    this->trix4 = this->Trix9(MME3,numDias);

    // pontos do grafico MA4
    this->ma = this->MA4(fechamento,numDias);
}


/** Calcula a primeira media exponencial
* Esse calculo eh realizado da seguinte forma:
* MME =  k*fechamento[anterior] + (1 - k)*fechamento[atual];
* Onde o ultimo valor do MME eh sempre uma media movel simples.
*
* @param <double> fechamento[]  vetor com todos os fechamentos a ser calculado
* @param <int> numDias quanidade de dias utilizado no vetor de fechamentos
* @return <double> MME1[] vetor com todos os valores da media exponencial dos fechamentos
*/
double* Trix::EMAClose1(double *fechamento, int numDias){

    int tamanho = numDias - this->periodo;
    double *MME1 = new double[tamanho];

    int i = 0;

    for(i = 0; i < tamanho-1;i++){
     MME1[i] = this->k*fechamento[i] + (1 - this->k)*fechamento[i+1];
    }

    double m = 0;
    for (int j = i; j < numDias-1 ;j++){
       m = m + fechamento[j];
    }

    double media =  m/this->periodo;

     MME1[i] = media;

return MME1;
}

/** Calcula a segunda e terceira media exponencial
 * Esse calculo eh realizado da seguinte forma:
 * MME = k*MMEClose[anterior] + (1 - k)*MME[atual];
 * Onde o ultimo valor desse vetor eh determinado pela media movel simples da MME
 *
 * @param <double> MMEClose[] vetor com os valores calculados na MME anterior
 * @param <int> numDias quantidade de dias utilizado para o fechamento
 * @return <double> MME[]  vetor com todos os valores da media exponencial
*/
double* Trix::EMAClose2And3(double *MMEClose, int numDias){

    int tamanho = numDias - 2*this->periodo;

    double *MME = new double[tamanho+1];
    double m = 0;

    int tamanhoMMEClose = numDias - this->periodo ;


    for(int i = tamanho; i < tamanhoMMEClose ;i++){
         m = m + MMEClose[i];
    }

    MME[tamanho] = m/this->periodo;

    for(int i = 1; i < tamanho+1 ; i++){
        MME[tamanho - i] = this->k*MMEClose[tamanho - i] + (1 - this->k)*MME[tamanho -i +1];
    }

    return MME;
}

/** Realiza do calculo dos valores do Trix9
 * Esse calculo eh realizado da seguinte forma:
 * tri9x = ((MMEclose3[anterior] - MMEclose3[atual])/(MMEclose3[atual]))*100;
 *
 * @param <double> MMEClose3  vetor com os valores calculados na MME3
 * @param <int> numDias quantidade de dias utilizado para o fechamento
 * @return <double> trix9[] vetor com todos os pontos do grafico Trix9
*/
double* Trix::Trix9(double *MMEclose3,int numDias){
    int tamanho = numDias - 3*this->periodo -1;
    double *trix9 = new double [tamanho];

    for(int i = 0; i< tamanho; i++){
        trix9[i] = ((MMEclose3[i] - MMEclose3[i + 1])/(MMEclose3[i + 1]))*5000;
//         cout<< trix9[i] <<"\n";
    }

return trix9;

}

/** Calcula a media movel simples do vetor de fechamentos para os pontos do grafico MA4
*
* @param <double> fechamento[] vetor com todos os fechamentos a ser calculado
* @param <int> numDias quantidade de dias utilizado para o fechamento
* @return <double> ma4[] vetor com todos os pontos do grafico MA4
*/
double* Trix::MA4(double *fechamento,int numDias){
    double fechamento_in[numDias];
    for(int i =0 ; i < numDias; i++){
        fechamento_in[i] = fechamento[numDias-i];
    }
    int tamanho = numDias - 3;
    double *ma4 = new double [tamanho];
    double m;

     for(int i = 0; i < tamanho; i++){
          m = 0 ;
         for(int j = 0; j< 3; j++){
              m = m + fechamento[i + j];

         }
         ma4[i] =  m/3;
     }

    return ma4;
}
